package cn.iocoder.yudao.module.book.service.audio;

import cn.iocoder.yudao.module.book.controller.app.bookcase.vo.AppBooksRespVO;
import cn.iocoder.yudao.module.book.controller.app.eargrinding.vo.AppAudioRespVO;
import cn.iocoder.yudao.module.book.service.books.BooksService;
import cn.iocoder.yudao.module.book.service.images.bookImagesService;
import cn.iocoder.yudao.module.book.service.users.userDTOService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;
import cn.iocoder.yudao.module.book.controller.admin.audio.vo.*;
import cn.iocoder.yudao.module.book.dal.dataobject.audio.AudioDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.book.dal.mysql.audio.AudioMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.book.enums.ErrorCodeConstants.*;
import cn.iocoder.yudao.module.book.controller.app.readBook.vo.AppbookImagesRespVO;
import cn.iocoder.yudao.module.book.dal.dataobject.images.bookImagesDO;

/**
 * 音频 Service 实现类
 *
 * @author xi
 */
@Service
@Validated
public class AudioServiceImpl implements AudioService {

    @Resource
    private AudioMapper audioMapper;

    @Resource
    private userDTOService userService;

    @Resource
    private BooksService booksService;

    @Resource
    private bookImagesService bookImagesService;

    @Override
    public Integer createAudio(AudioSaveReqVO createReqVO) {
        // 插入
        AudioDO audio = BeanUtils.toBean(createReqVO, AudioDO.class);
        audioMapper.insert(audio);
        // 返回
        return audio.getAudioId();
    }

    @Override
    public void updateAudio(AudioSaveReqVO updateReqVO) {
        // 校验存在
        validateAudioExists(updateReqVO.getAudioId());
        // 更新
        AudioDO updateObj = BeanUtils.toBean(updateReqVO, AudioDO.class);
        audioMapper.updateById(updateObj);
    }

    @Override
    public void deleteAudio(Integer id) {
        // 校验存在
        validateAudioExists(id);
        // 删除
        audioMapper.deleteById(id);
    }

    private void validateAudioExists(Integer id) {
        if (audioMapper.selectById(id) == null) {
            throw exception(AUDIO_NOT_EXISTS);
        }
    }

    @Override
    public AudioDO getAudio(Integer id) {
        return audioMapper.selectById(id);
    }

    @Override
    public PageResult<AudioDO> getAudioPage(AudioPageReqVO pageReqVO) {
        return audioMapper.selectPage(pageReqVO);
    }


    @Override
    public List<AppAudioRespVO> getRecentAudio(Long userId) {
        LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7);
        return audioMapper.getRecentAudio(userId,sevenDaysAgo);
    }

    @Override
    public void saveRecording(Long bookId, Integer page, String fileUrl) {
        Long userId = userService.getCurrentUserId();
        AudioDO latest = audioMapper.selectLatestByUserBookPage(userId, Long.valueOf(bookId), page);
        if (latest != null) {
            audioMapper.updateUrlByUserBookPage(userId, Long.valueOf(bookId), page, fileUrl);
        } else {
            AudioDO audio = new AudioDO();
            audio.setBookId(Long.valueOf(bookId));
            audio.setAudioUrl(fileUrl);
            audio.setUserId(userId);
            audio.setPage(page);
            audioMapper.insertRecord(audio);
        }
    }

    @Override
    public void saveRecordingData(Long bookId, Integer page, byte[] data, String contentType) {
        Long userId = userService.getCurrentUserId();
        AudioDO latest = audioMapper.selectLatestByUserBookPage(userId, Long.valueOf(bookId), page);
        if (latest != null) {
            audioMapper.updateDataByUserBookPage(userId, Long.valueOf(bookId), page, data, contentType);
        } else {
            AudioDO audio = new AudioDO();
            audio.setBookId(Long.valueOf(bookId));
            audio.setUserId(userId);
            audio.setAudioData(data);
            audio.setContentType(contentType);
            audio.setPage(page);
            audioMapper.insertRecord(audio);
        }
    }

    @Override
    public AudioDO getLatestRecording(Long userId, Long bookId, Integer page) {
        return audioMapper.selectLatestByUserBookPage(userId, bookId, page);
    }

    @Override
    public AppAudioRespVO playAudio(Integer bookId, Long userId) {
        // 1. 获取书籍信息
        AppBooksRespVO book = booksService.getByBookId(bookId, null);
        if (book == null) {
            throw exception(BOOK_NOT_EXISTS);
        }

        // 2. 获取书籍的第一张图片的音频信息
        List<AppbookImagesRespVO> bookImages = bookImagesService.getBookImagesByBookId(bookId);
        if (bookImages == null || bookImages.isEmpty()) {
            throw exception(BOOK_NOT_EXISTS);
        }

        // 获取第一张图片的音频URL
        String audioUrl = bookImages.get(0).getAudioUrl();
        if (audioUrl == null || audioUrl.isEmpty()) {
            throw exception(BOOK_NOT_EXISTS);
        }

        // 3. 记录播放行为到audio表
        AudioDO audio = new AudioDO();
        audio.setBookId(Long.valueOf(bookId));
        audio.setUserId(userId);
        audio.setAudioUrl(audioUrl);
        audioMapper.insertRecord(audio);

        // 4. 返回音频播放信息
        AppAudioRespVO audioResp = new AppAudioRespVO();
        audioResp.setBookId(bookId);
        audioResp.setAudioUrl(audioUrl);
        audioResp.setProgressSeconds(0);
        audioResp.setCreateTime(LocalDateTime.now());

        return audioResp;
    }

    @Override
    public AppAudioRespVO playPageAudio(Integer bookId, Integer imageId, Long userId) {
        // 1. 获取书籍信息
        AppBooksRespVO book = booksService.getByBookId(bookId, null);
        if (book == null) {
            throw exception(BOOK_NOT_EXISTS);
        }

        // 2. 获取指定图片的音频信息
        bookImagesDO bookImage = bookImagesService.getbookImages(imageId);
        if (bookImage == null || !bookImage.getBookId().equals(bookId)) {
            throw exception(BOOK_NOT_EXISTS);
        }

        String audioUrl = bookImage.getAudioUrl();
        if (audioUrl == null || audioUrl.isEmpty()) {
            throw exception(BOOK_NOT_EXISTS);
        }

        // 3. 记录播放行为到audio表
        AudioDO audio = new AudioDO();
        audio.setBookId(Long.valueOf(bookId));
        audio.setUserId(userId);
        audio.setAudioUrl(audioUrl);
        audioMapper.insertRecord(audio);

        // 4. 返回音频播放信息
        AppAudioRespVO audioResp = new AppAudioRespVO();
        audioResp.setBookId(bookId);
        audioResp.setAudioUrl(audioUrl);
        audioResp.setProgressSeconds(0);
        audioResp.setCreateTime(LocalDateTime.now());

        return audioResp;
    }

    @Override
    public List<Long> listMyRecordedBookIds(Long userId) {
        return audioMapper.selectDistinctBookIdsByUser(userId);
    }

}